home *** CD-ROM | disk | FTP | other *** search
- /*
- * The original copyright owners of the accompanying source code files have
- * agreed to place such code into the public domain. Accordingly, anyone
- * who receives or obtains a copy of such source code is freely entitled to
- * reproduce, use and otherwise exploit such code (including the right to
- * make derivative works), at his/her own risk and expense, without any
- * obligation or liability to the original copyright owners.
- *
- * We would appreciate (but do not require) that the following message be
- * included in any derivative works:
- *
- * "Portions of this program were developed by Peter Broadwell, Rob Myers
- * and Robin Schaufler while working in Silicon Valley."
- *
- * The accompanying source code files and related documentation materials
- * are distributed on an "AS IS" basis, without any warranties or
- * guarantees of any kind. All implied warranties, including the implied
- * warranties of merchantability and of fitness for any particular purpose,
- * are expressly disclaimed.
- */
- #include <stdio.h>
- #include <math.h>
- #include "gl.h"
- #include "device.h"
- #include "geom.h"
- #include "class.h"
- #include "selectors.h"
- #include "classIds.h"
- #include "mbox.h"
- #include "individual.h"
- #include "behavior.h"
- #include "doers.h"
- #include "bub.h"
- #include "sea.h"
- #include "pick.h"
- #include "colors.h"
-
- extern individual *us;
- extern individual bubbleTemplate;
- extern behavior advancerTemplate;
- extern behavior expanderTemplate;
- extern behavior surfDieTemplate;
- extern individual *curIndiv;
-
- #define MAXBUBBLES 125
-
- individual * bubStack[MAXBUBBLES];
- static long bubcount;
- static long newbub;
- extern int inNothing;
- extern int controls;
-
- behavior *curBehave = NULL;
-
- /*
- * cough up a new bubble (or recycle an old dead one)
- */
-
- individual *
- makeBub()
- {
- individual *bub;
-
- if(bubcount == 0) {
- newbub = TRUE;
- return (individual *)clone(&bubbleTemplate);
- }
- else {
- newbub = FALSE;
- bub = bubStack[bubcount--];
- bub->velocity.z = (&bubbleTemplate)->velocity.z;
- return bub;
- }
- }
-
- eatBub(bub)
- individual * bub;
- {
- if(++bubcount >= MAXBUBBLES) {
- fprintf(stderr,"trying to eat to much\n");
- return;
- }
- bubStack[bubcount] = bub;
- }
-
- /*
- * pop this bubble, store for reuse
- */
- bubblefree(self)
- register individual *self;
- {
- register subscr *s;
-
- dumpSubscribers("bubble's subscribers", self->them.subscribers, 0);
- while (s = self->them.subscribers)
- unsubscribe(self, s->member);
-
- dumpSubscribers("bubble's subscribedTos", self->them.subscribedTo, 0);
- while (s = self->them.subscribedTo)
- unsubscribe(s->member, self);
-
- if (self == curIndiv)
- curIndiv = NULL;
-
- /**********
- freeMsegs(self->descr);
- ***********/
- eatBub(self);
- }
-
- /*
- * init the bubble machine
- */
- /* ARGSUSED */
- bubbleMachine *
- blowInit(s)
- register bubbleMachine *s;
- {
- /*********
- behavior **pb;
-
- for (pb = s->doers; pb && *pb; pb++) {
- if ((*pb)->them.me.myClass)
- printf("bub templ %d\n", (*pb)->them.me.myClass->classId);
- else
- printf("bub templ has null myClass ptr\n");
- }
- **********/
- }
-
- /*
- * blow a new bubble
- */
- bubbleMachine *
- blowBubble(s)
- register bubbleMachine *s;
- {
- register bubble *bub;
- expanderVars *vars;
- bubble *templ;
- behavior *doer;
-
- if (s->bubbleDispatchIncr && s->bubbleClock % s->bubbleDispatchIncr == 0) {
- bub = (bubble *)makeBub();
- subscribe(us, bub);
- doer = s->doers[s->bubbleDoer];
- templ = (bubble *)doer->bubtemplate;
- if (templ->doer != doer) {
- printf("blow: doer = %x,%d, templ->doer = %x,%d\n",
- doer,
- doer->them.me.myClass->classId,
- templ->doer,
- ((behavior *)templ->doer)->them.me.myClass->classId);
- }
- *bub->me.descr = *templ->me.descr;
- bub->doer = templ->doer;
-
- subscribe(&advancerTemplate, bub);
- subscribe(&expanderTemplate, bub);
- subscribe(&surfDieTemplate, bub);
- Msg(bub, INIT, NOARG, NULL);
-
- if (vars = (expanderVars *)findvars(bub, EXPANDER)) {
- /* bubbles will expand to different sizes */
- vars->scaleMax = abs((float)sin(s->bubbleClock/3.5) * 40.0) +
- 10.0;
-
- /* some bubbles go faster */
- if (s->bubbleSpeedupIncr &&
- s->bubbleClock % s->bubbleSpeedupIncr == 0)
- bub->me.velocity.z += vars->scaleMax * 1.3;
- }
-
- bub->me.position.x = s->me.position.x;
- bub->me.position.y = s->me.position.y;
- bub->me.position.z = s->me.position.z;
-
- bub->me.lastPosition.x = bub->me.position.x - bub->me.velocity.x;
- bub->me.lastPosition.y = bub->me.position.y - bub->me.velocity.y;
- bub->me.lastPosition.z = bub->me.position.z - bub->me.velocity.z;
- /* printf("blowBubble: new bubble 0x%x\n", bub); /* */
-
- if (s->doers[++s->bubbleDoer] == NULL)
- s->bubbleDoer = 0;
- }
- s->bubbleClock++;
- return s;
- }
-
- /*
- * initialize a bubble's drawing
- */
- bubbleinit(s)
- register individual *s;
- {
- register model *myModel;
-
- /* first, instantiate and initialize the model */
- if(newbub) replicateModel(s);
- myModel = s->descr; /* use newly instantiated model */
-
- makeobj((Object)myModel);
- pushLongName(s);
- backface(FALSE);
- fishWritemask(FOREGROUND);
- fishColor(myModel->color);
- scale(-1.0, 1.0, -1.0);
- #define WIMP
- #ifdef WIMP
- rotate(900,'z');
- rotate(900,'y');
- #endif /* WIMP */
- circi(10,0,12);
- circfi(7,4,2);
- backface(TRUE);
- fishWritemask(NOGROUND);
- rectfi(-4,14,24,-14);
- popLongName();
- closeobj();
- myModel->compiled = TRUE;
- myModel->component = (Object)myModel;
- }
-
- /* ARGSUSED */
- selectBub(self, argtype, hit)
- register bubble *self;
- long argtype;
- hitstruct *hit;
- {
- inNothing = FALSE;
-
- if (self->doer != curBehave) {
- }
- curBehave = self->doer;
- if (! curBehave) {
- fprintf(stderr,"Got a bub with NULL doer\n");
- return;
- }
- /* printf("Got a bub for %d\n", self->doer->them.me.myClass->classId); /* */
- if (curIndiv)
- Msg(curIndiv, POSTBEHAVE, sizeof(behavior), curBehave);
- else /* send notice to us on behalf of no current indiv */
- Msg(us, POSTBEHAVE, sizeof(behavior), curBehave);
- controls = TRUE;
- }
-